/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package config;

//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

public class Settings implements Serializable {
	// CONSTANT DICLARATION

	public static final int BOX_TYPE_MENUBOX = 0;
	public static final int BOX_TYPE_AUTOBOX = 1;
	public static final int BOX_TYPE_REALESTATEBOX = 2;
	/* Constants */

	static {
		// Settings.load();
	}
	public static final int FTP_CONNECTION = 0;
	public static final int HTTP_CONNECTION = 1;

	public static final String[] MYSQL_PLAYER_TABLES = new String[] { "playlist", "playlist_record", "page", "content", "container", "inventory",
			"inventory_definition" };
	public static final double VERSION = 7.07;
	// TODO: boolean auto update player
	/** admin frame **/
	/** debug messages will be printed if debug is enabled */
	public static final boolean DEBUG_ENABLED = true;
	public static final String BOXDATA_HTTP_DIRECTORY = "http://www.digitalmarketingbox.com/webtool/boxdata/";
	public static final String INVENTORY_HTTP_DIRECTORY = "http://www.digitalautobox.com/";
	public static final String REALESTATE_HTTP_DIRECTORY = "http://www.digitalrealestatebox.com";
	public static final String DMB_DOMAIN = "http://www.digitalmarketingbox.com";
	public static final String UPDATE_CHECKER_URL = "http://www.digitalmarketingbox.com/webtool/playerupdate.php";
	public static final String UPDATE_CHECKER_URL_TOKEN = "dmb20101512";
	public static final String CONFIG_FILE = "settings.txt";
	public static final String PLAYER_EXECUTABLE = "dmbplayer.jar";

	private static Connection localDatabaseConnection;
	private static boolean databaseIsAccessible = true;
	private static int connectionType = FTP_CONNECTION;
	static Map<String, String> prefFormat = new HashMap<String, String>();

	public static int getBoxType() {
		return boxType;
	}

	public static void setBoxType(int boxType) {
		Settings.boxType = boxType;
	}

	private static int boxType = Settings.BOX_TYPE_MENUBOX;
	// GLOBAL VARIABLE DELCARATION
	/** The id that uniquely identifies this player */
	private static int boxId = 851;// Java Demo Player
	/**
	 * set the ratio for how the images/containers of the player should be
	 * scaled, scale = 1 is normal size, scale > 0
	 */
	private static double scale = 1;
	private static int updateCheckerFrequency = 90; // in seconds
	private static int upgradeCheckerFrequency = 60 * 10; // in seconds

	public static int getUpdateCheckerFrequency() {
		return updateCheckerFrequency;
	}

	public static void setUpdateCheckerFrequency(int updateCheckerFrequency) {
		Settings.updateCheckerFrequency = updateCheckerFrequency;
	}

	public static int getConnectionType() {
		return connectionType;
	}

	public static void setConnectionType(int connectionType) {
		Settings.connectionType = connectionType;
	}

	/* directories used by the player */
	private static String resourceDirectory = "resources" + File.separator;
	private static String imageDirectory = "resources" + File.separator + "images" + File.separator;

	public static int getUpgradeCheckerFrequency() {
		return upgradeCheckerFrequency;
	}

	public static void setUpgradeCheckerFrequency(int upgradeCheckerFrequency) {
		Settings.upgradeCheckerFrequency = upgradeCheckerFrequency;
	}

	private static String videoDirectory = "resources" + File.separator + "videos" + File.separator;
	private static String htmlDirectory = "resources" + File.separator + "html" + File.separator;
	private static String downloadDirectory = "resources" + File.separator + "downloads" + File.separator;
	private static String csvDirectory = "resources" + File.separator + "csv" + File.separator;
	private static String sqlDirectory = "resources" + File.separator + "sql" + File.separator;
	private static String scriptDirectory = "resources" + File.separator + "scripts" + File.separator;
	private static String settingsDirectory = "resources" + File.separator + "settings" + File.separator;
	private static String logsDirectory = "resources" + File.separator + "logs" + File.separator;
	private static String newPlayerDirectory = "resources" + File.separator + "player" + File.separator;
	private static String coreDataDirectory = "resources" + File.separator + "coredata" + File.separator;

	public static String getCoreDataDirectory() {
		return coreDataDirectory;
	}

	public static void setCoreDataDirectory(String coreDataDirectory) {
		Settings.coreDataDirectory = coreDataDirectory;
	}

	private static String seoUrlFile = "resources" + File.separator + "addresses.txt";

	public static String getNewPlayerDirectory() {
		return newPlayerDirectory;
	}

	public static void setNewPlayerDirectory(String newPlayerDirectory) {
		Settings.newPlayerDirectory = newPlayerDirectory;
	}

	private static int playerWidth = 1080; /* defines the width of the player */

	private static int playerHeight = 1920; /* defines the height of the player */

	/* Mysql Database Connection Settings */
	private static String localMysqlServer = "localhost";
	private static String localMysqlDatabase = "player_db";
	private static String localMysqlUsername = "root";
	private static String localMysqlPassword = "";

	/* Webtool FTP Connection Settings */
	private static String webtoolFtpHost = "ftp.digitalmarketingbox.com";
	private static String webtoolFtpUser = "player@digitalmarketingbox.com";
	private static String webtoolFtpPassword = "JJS6ACHF2C8T";
	/* autobox Ftp Settings */
	private static String autoboxFtpHost = "ftp.digitalmarketingbox.com";
	private static String autoboxFtpUser = "player1@digitalmarketingbox.com";
	private static String autoboxFtpPassword = "JJS6ACHF2C8T";

	private static String realEstateFtpHost = "ftp.digitalrealestatebox.com";

	private static String realEstateFtpUser = "player@digitalrealestatebox.com";
	private static String realEstateFtpPassword = "JJS6ACHF2C8T";

	private static String resourcesFileName = "resources.zip";
	private static boolean blankPlayer = true;
	private static String adminPassword = "street";
	private static int numberOfErrorsOccured = 0;

	public static int getNumberOfErrorsOccured() {
		return numberOfErrorsOccured;
	}

	public static void setNumberOfErrorsOccured(int numberOfErrorsOccured) {
		Settings.numberOfErrorsOccured = numberOfErrorsOccured;
	}

	public static String getHtmlResourceFileLocation() {

		String result = Settings.boxId + "/" + Settings.resourcesFileName;
		return result;
	}

	public static String getAdminPassword() {
		return adminPassword;
	}

	public static void setAdminPassword(String adminPassword) {
		Settings.adminPassword = adminPassword;
	}

	/**
	 * Get the JDBC connection string for MySql
	 * 
	 * @return the JDBC connection string for MySql
	 */
	public static String getLocalMysqlConnectionString() {
		return String.format("jdbc:mysql://%1$s/%2$s?user=%3$s&password=%4$s", getLocalMysqlServer(), getLocalMysqlDatabase(), getLocalMysqlUsername(),
				getLocalMysqlPassword());
	}

	public static void main(String[] args) {
		System.out.println(Settings.playerHeight);
		System.out.println(Settings.playerWidth);
		// playerWidth = 5000;
		// Settings s = new Settings();
		// s.saveSettings();
		// Settings.loadSettings();
		System.out.println(Settings.boxId);
		System.out.println(Settings.playerHeight);
		System.out.println(Settings.playerWidth);
	}

	public static void resetConfiguration() {
		// TODO : remove settings
		// do nothing now
	}

	public static boolean isConfigFileExist() {
		File configFile = new File(CONFIG_FILE);
		if (configFile.isFile()) {
			return true;
		}
		return false;
	}

	/**
	 * Code to serialize the settings
	 * 
	 */

	private void writeObject(ObjectOutputStream os) throws IOException {
		os.defaultWriteObject();
		// write integers
		os.writeInt(boxId);
		os.writeInt(playerWidth);
		os.writeInt(playerHeight);
		os.writeInt(connectionType);
		os.writeInt(updateCheckerFrequency);
		os.writeInt(upgradeCheckerFrequency);
		os.writeInt(numberOfErrorsOccured);
		os.writeInt(boxType);
		// write booleans
		os.writeBoolean(blankPlayer);
		// write doubles
		os.writeDouble(scale);
		// write objects

		os.writeObject(localMysqlServer);
		os.writeObject(localMysqlDatabase);
		os.writeObject(localMysqlUsername);
		os.writeObject(localMysqlPassword);
		os.writeObject(webtoolFtpHost);
		os.writeObject(webtoolFtpUser);
		os.writeObject(webtoolFtpPassword);
		os.writeObject(autoboxFtpHost);
		os.writeObject(autoboxFtpUser);
		os.writeObject(autoboxFtpPassword);
	}

	/**
	 * Code to deserialize the settings
	 * 
	 */
	private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {
		is.defaultReadObject();
		boxId = is.readInt();
		playerWidth = is.readInt();
		playerHeight = is.readInt();
		connectionType = is.readInt();
		updateCheckerFrequency = is.readInt();
		upgradeCheckerFrequency = is.readInt();
		numberOfErrorsOccured = is.readInt();
		boxType = is.readInt();
		blankPlayer = is.readBoolean();

		scale = is.readDouble();

		localMysqlServer = (String) is.readObject();
		localMysqlDatabase = (String) is.readObject();
		localMysqlUsername = (String) is.readObject();
		localMysqlPassword = (String) is.readObject();
		webtoolFtpHost = (String) is.readObject();
		webtoolFtpUser = (String) is.readObject();
		webtoolFtpPassword = (String) is.readObject();
		autoboxFtpHost = (String) is.readObject();
		autoboxFtpUser = (String) is.readObject();
		autoboxFtpPassword = (String) is.readObject();
	}

	public static boolean isBlankPlayer() {
		return blankPlayer;
	}

	public static void setBlankPlayer(boolean blankPlayer) {
		Settings.blankPlayer = blankPlayer;
	}

	/**
	 * The <b>saveSettings()</b> function saves the settings in the config file
	 * for future use
	 * 
	 */
	public static void saveSettings() {
		FileOutputStream fs = null;
		ObjectOutputStream os = null;
		Settings s = new Settings();
		try {
			fs = new FileOutputStream(CONFIG_FILE);
			os = new ObjectOutputStream(fs);
			os.writeObject(s);
		} catch (IOException e) {
			Debug.log("Settings.saveSettings(): Unable to write config file.", Debug.ERROR_LEVEL);
		} finally {
			try {
				if (fs != null)
					fs.close();
			} catch (IOException ex) {
				Debug.log("Settings.saveSettings(): Unable to close FileOutputStream.", Debug.ERROR_LEVEL);
			}
			try {
				if (os != null)
					os.close();
			} catch (IOException ex) {
				Debug.log("Settings.saveSettings(): Unable to close ObjectOutputStream.", Debug.ERROR_LEVEL);
			}
		}
	}

	public static void load() {
		prefFormat.put("box_id", "int");
		prefFormat.put("player_width", "int");
		prefFormat.put("player_height", "int");
		prefFormat.put("update_frequency", "int");
		prefFormat.put("transfer_by_http", "int");
		prefFormat.put("scale", "double");
		prefFormat.put("local_mysql_host", "string");
		prefFormat.put("local_mysql_database", "string");
		prefFormat.put("local_mysql_username", "string");
		prefFormat.put("local_mysql_password", "string");
		prefFormat.put("reset_on_startup", "boolean");
		Preferences prefs = Preferences.userRoot();
		File f = new File(Settings.CONFIG_FILE);
		if (!f.exists()) {
			try {
				f.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		Scanner s = null;
		try {
			s = new Scanner(f);
			while (s.hasNext()) {
				String line = s.nextLine();
				String[] tokens = line.split("=");
				for (int i = 0; i < tokens.length; i++) {
					tokens[i] = tokens[i].trim();
				}
				if (tokens.length != 2 || tokens[1].charAt(tokens[1].length() - 1) != ';') {
					continue;
				}
				tokens[1] = tokens[1].substring(0, tokens[1].length() - 1);
				String key = tokens[0];
				assert (tokens[0] != null && tokens[1] != null);
				try {
					if (prefFormat.get(key) == null) {
						System.out.println("preference ignored: " + key);
					} else if (prefFormat.get(key).equalsIgnoreCase("int")) {
						prefs.putInt(key, Integer.parseInt(tokens[1]));
					} else if (prefFormat.get(key).equalsIgnoreCase("double")) {
						prefs.putDouble(key, Double.parseDouble(tokens[1]));
					} else if (prefFormat.get(key).equalsIgnoreCase("string")) {
						prefs.put(key, tokens[1]);
					} else if (prefFormat.get(key).equalsIgnoreCase("boolean")) {
						prefs.putBoolean(key, Boolean.parseBoolean(tokens[1]));
					}
				} catch (NumberFormatException ex) {
					Debug.log("Wrong Number format while reading settings file: " + tokens[1], Debug.ERROR_LEVEL);
				}
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (s != null) {
				s.close();
			}
		}
		Settings.boxId = prefs.getInt("box_id", Settings.getBoxId());
		Settings.playerWidth = prefs.getInt("player_width", Settings.getPlayerWidth());
		Settings.playerHeight = prefs.getInt("player_height", Settings.getPlayerHeight());
		Settings.updateCheckerFrequency = prefs.getInt("update_frequency", Settings.getUpdateCheckerFrequency());
		Settings.connectionType = prefs.getInt("transfer_by_http", Settings.getConnectionType());
		Settings.setScale(prefs.getDouble("scale", Settings.getScale()));
		Settings.localMysqlServer = prefs.get("local_mysql_host", Settings.getLocalMysqlServer());
		Settings.localMysqlDatabase = prefs.get("local_mysql_database", Settings.getLocalMysqlDatabase());
		Settings.localMysqlUsername = prefs.get("local_mysql_username", Settings.getLocalMysqlUsername());
		Settings.localMysqlPassword = prefs.get("local_mysql_password", Settings.getLocalMysqlPassword());
		Settings.setBlankPlayer(prefs.getBoolean("reset_on_startup", Settings.isBlankPlayer()));
	}

	public static void save() {
		Preferences prefs = Preferences.userRoot();

		prefs.putInt("box_id", Settings.getBoxId());
		prefs.putInt("player_width", Settings.getPlayerWidth());
		prefs.putInt("player_height", Settings.getPlayerHeight());
		prefs.putInt("update_frequency", Settings.getUpdateCheckerFrequency());
		prefs.putInt("transfer_by_http", Settings.getConnectionType());
		prefs.putDouble("scale", Settings.getScale());
		prefs.put("local_mysql_host", Settings.getLocalMysqlServer());
		prefs.put("local_mysql_database", Settings.getLocalMysqlDatabase());
		prefs.put("local_mysql_username", Settings.getLocalMysqlUsername());
		prefs.put("local_mysql_password", Settings.getLocalMysqlPassword());
		prefs.putBoolean("reset_on_startup", Settings.isBlankPlayer());

		FileWriter fr = null;
		try {
			fr = new FileWriter(new File(Settings.CONFIG_FILE));
			StringBuilder sb = new StringBuilder();
			List<String> prefList = new ArrayList<String>();
			for (String key : prefs.keys()) {
				prefList.add(key);
			}
			Collections.sort(prefList);
			for (String key : prefList) {
				sb.append(key).append("=").append(prefs.get(key, null)).append(";\n");
			}
			fr.write(sb.toString());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			Debug.log(e.toString(), Debug.ERROR_LEVEL);
			e.printStackTrace();
		} catch (BackingStoreException e) {
			// TODO Auto-generated catch block
			Debug.log(e.toString(), Debug.ERROR_LEVEL);
			e.printStackTrace();
		} finally {
			if (fr != null) {
				try {
					fr.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

	}

	public static Settings loadSettings() {
		FileInputStream fis = null;
		ObjectInputStream ois = null;
		if (!Settings.isConfigFileExist()) {
			return null;
		}
		Settings s = null;
		try {
			fis = new FileInputStream(CONFIG_FILE);
			ois = new ObjectInputStream(fis);
			s = (Settings) ois.readObject();

		} catch (IOException e) {
			Debug.log("Settings.loadSettings() Unable to read config file.", Debug.ERROR_LEVEL);
		} catch (ClassNotFoundException e) {
			Debug.log("Settings.saveSettings() " + e.getMessage(), Debug.ERROR_LEVEL);
		} finally {
			try {
				if (fis != null)
					fis.close();
			} catch (IOException ex) {
				Debug.log("Settings.loadSettings(): Unable to close FileInputStream.", Debug.ERROR_LEVEL);
			}
			try {
				if (ois != null)
					ois.close();
			} catch (IOException ex) {
				Debug.log("Settings.loadSettings(): Unable to close ObjectInputStream.", Debug.ERROR_LEVEL);
			}
		}
		return s;
	}

	public static Connection getLocalDatabaseConnection() {
		if (localDatabaseConnection == null && databaseIsAccessible) {
			try {
				localDatabaseConnection = DriverManager.getConnection(getLocalMysqlConnectionString());
			} catch (SQLException ex) {
				Debug.showDatabaseAccessErrorAlert(ex.getMessage());
			}
		}
		return localDatabaseConnection;
	}

	public static boolean isDatabaseIsAccessible() {
		return databaseIsAccessible;
	}

	public static void setDatabaseIsAccessible(boolean databaseIsAccessible) {
		Settings.databaseIsAccessible = databaseIsAccessible;
	}

	public static String getWebtoolHttpUpdateFile() {
		return BOXDATA_HTTP_DIRECTORY + Settings.getBoxId() + "/" + resourcesFileName;
	}

	public static String getResourcesFileName() {
		return resourcesFileName;
	}

	public static void setResourcesFileName(String resourcesFileName) {
		Settings.resourcesFileName = resourcesFileName;
	}

	public static String getWebtoolFtpUpdateFile() {
		return String.format("/webtool/boxdata/%1$d/" + resourcesFileName, Settings.getBoxId());
	}

	// setters and getters start here
	// ********************************************************************************************************************************************************//
	// ********************************************************************************************************************************************************//
	// ********************************************************************************************************************************************************//
	// ********************************************************************************************************************************************************//
	// ********************************************************************************************************************************************************//

	public static int getBoxId() {
		return boxId;
	}

	public static void setBoxId(int boxId) {
		Settings.boxId = boxId;
	}

	public static String getCsvDirectory() {
		return csvDirectory;
	}

	public static void setCsvDirectory(String csvDirectory) {
		Settings.csvDirectory = csvDirectory;
	}

	public static String getDownloadDirectory() {
		return downloadDirectory;
	}

	public static void setDownloadDirectory(String downloadDirectory) {
		Settings.downloadDirectory = downloadDirectory;
	}

	public static String getHtmlDirectory() {
		return htmlDirectory;
	}

	public static void setHtmlDirectory(String htmlDirectory) {
		Settings.htmlDirectory = htmlDirectory;
	}

	public static String getImageDirectory() {
		return imageDirectory;
	}

	public static void setImageDirectory(String imageDirectory) {
		Settings.imageDirectory = imageDirectory;
	}

	public static String getLocalMysqlDatabase() {
		return localMysqlDatabase;
	}

	public static void setLocalMysqlDatabase(String localMysqlDatabase) {
		Settings.localMysqlDatabase = localMysqlDatabase;
	}

	public static String getLocalMysqlPassword() {
		return localMysqlPassword;
	}

	public static void setLocalMysqlPassword(String localMysqlPassword) {
		Settings.localMysqlPassword = localMysqlPassword;
	}

	public static String getLocalMysqlServer() {
		return Settings.localMysqlServer;
	}

	public static void setLocalMysqlServer(String localMysqlServer) {
		Settings.localMysqlServer = localMysqlServer;
	}

	public static String getLocalMysqlUsername() {
		return localMysqlUsername;
	}

	public static void setLocalMysqlUsername(String localMysqlUsername) {
		Settings.localMysqlUsername = localMysqlUsername;
	}

	public static String getLogsDirectory() {
		return logsDirectory;
	}

	public static void setLogsDirectory(String logsDirectory) {
		Settings.logsDirectory = logsDirectory;
	}

	public static int getPlayerHeight() {
		return playerHeight;
	}

	public static void setPlayerHeight(int playerHeight) {
		Settings.playerHeight = playerHeight;
	}

	public static int getPlayerWidth() {
		return playerWidth;
	}

	public static void setPlayerWidth(int playerWidth) {
		Settings.playerWidth = playerWidth;
	}

	public static String getResourceDirectory() {
		return resourceDirectory;
	}

	public static void setResourceDirectory(String resourceDirectory) {
		Settings.resourceDirectory = resourceDirectory;
	}

	public static double getScale() {
		return scale;
	}

	public static void setScale(double scale) {
		if (scale > 1) {
			scale = 1;
		} else if (scale < 0.1) {
			scale = 0.1;
		}
		Settings.scale = scale;
	}

	public static String getScriptDirectory() {
		return scriptDirectory;
	}

	public static void setScriptDirectory(String scriptDirectory) {
		Settings.scriptDirectory = scriptDirectory;
	}

	public static String getSettingsDirectory() {
		return settingsDirectory;
	}

	public static void setSettingsDirectory(String settingsDirectory) {
		Settings.settingsDirectory = settingsDirectory;
	}

	public static String getSqlDirectory() {
		return sqlDirectory;
	}

	public static void setSqlDirectory(String sqlDirectory) {
		Settings.sqlDirectory = sqlDirectory;
	}

	public static String getVideoDirectory() {
		return videoDirectory;
	}

	public static void setVideoDirectory(String videoDirectory) {
		Settings.videoDirectory = videoDirectory;
	}

	public static String getWebtoolFtpHost() {
		return webtoolFtpHost;
	}

	public static void setWebtoolFtpHost(String webtoolFtpHost) {
		Settings.webtoolFtpHost = webtoolFtpHost;
	}

	public static String getWebtoolFtpPassword() {
		return webtoolFtpPassword;
	}

	public static void setWebtoolFtpPassword(String webtoolFtpPassword) {
		Settings.webtoolFtpPassword = webtoolFtpPassword;
	}

	public static String getWebtoolFtpUser() {
		return webtoolFtpUser;
	}

	public static void setWebtoolFtpUser(String webtoolFtpUser) {
		Settings.webtoolFtpUser = webtoolFtpUser;
	}

	public static String getAutoboxFtpHost() {
		return autoboxFtpHost;
	}

	public static void setAutoboxFtpHost(String autoboxFtpHost) {
		Settings.autoboxFtpHost = autoboxFtpHost;
	}

	public static String getAutoboxFtpPassword() {
		return autoboxFtpPassword;
	}

	public static void setAutoboxFtpPassword(String autoboxFtpPassword) {
		Settings.autoboxFtpPassword = autoboxFtpPassword;
	}

	public static String getAutoboxFtpUser() {
		return autoboxFtpUser;
	}

	public static void setAutoboxFtpUser(String autoboxFtpUser) {
		Settings.autoboxFtpUser = autoboxFtpUser;
	}

	public static String getRealEstateFtpHost() {
		return realEstateFtpHost;
	}

	public static void setRealEstateFtpHost(String realEstateFtpHost) {
		Settings.realEstateFtpHost = realEstateFtpHost;
	}

	public static String getRealEstateFtpUser() {
		return realEstateFtpUser;
	}

	public static void setRealEstateFtpUser(String realEstateFtpUser) {
		Settings.realEstateFtpUser = realEstateFtpUser;
	}

	public static String getRealEstateFtpPassword() {
		return realEstateFtpPassword;
	}

	public static void setRealEstateFtpPassword(String realEstateFtpPassword) {
		Settings.realEstateFtpPassword = realEstateFtpPassword;
	}

}
